package sys_serv

import (
	"strconv"
	"strings"
	"ubt-aio-service/app/mod/sys_mod"
	"ubt-aio-service/app/pkg/db"
	"ubt-aio-service/app/utils"
)

type sysLog struct{}

var SysLogServ = sysLog{}

// Add 新增日志
func (s *sysLog) Add(req *sys_mod.SysLogSaveReq) *utils.ResJson {
	sqlStr := "INSERT INTO sys_log(user_id, menu_code, ip_addr, kind, add_time) VALUES ($1, $2, $3, $4, EXTRACT(epoch FROM NOW()))"
	return db.CudData(sqlStr, req.UserId, req.MenuCode, req.IpAddr, req.Kind)
}

// Deletes 删除日志
func (s *sysLog) Deletes(req *sys_mod.SysLogDelsReq) *utils.ResJson {
	var (
		param []any
		q     string
		n     = 0
	)
	idList := strings.Split(req.LogIds, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE sys_log SET states=2, upd_time=EXTRACT(epoch FROM NOW()) WHERE log_id IN (" + q + ")"
	return db.CudData(sqlStr, param...)
}

// Count 获取日志数量
func (s *sysLog) Count(req *sys_mod.SysLogPageReq) *utils.ResJson {
	sqlStr := "SELECT COUNT(1) AS nums FROM sys_log WHERE 1=1"
	param := make([]any, 0)
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "ip_addr LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR "
			param = append(param, name)
			n++
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.UserId != "" {
		n++
		sqlStr += " AND user_id=$" + strconv.Itoa(n)
		param = append(param, req.UserId)
	}
	if req.MenuCode != "" {
		n++
		sqlStr += " AND menu_code=$" + strconv.Itoa(n)
		param = append(param, req.MenuCode)
	}
	if req.Kind != 0 {
		n++
		sqlStr += " AND kind=$" + strconv.Itoa(n)
		param = append(param, req.Kind)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND add_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND add_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code && res.Data.(map[string]any)["nums"].(int64) > 0 {
		return res
	}
	return utils.NoData
}

// Page 获取日志分页列表
func (s *sysLog) Page(req *sys_mod.SysLogPageReq) *utils.ResJson {
	sqlStr := "SELECT a.log_id, b.nick_name||'('||b.usname||')' log_user, c.menu_name||'['||c.menu_code||']' menu_name, a.ip_addr, a.kind, a.add_time " +
		"FROM sys_log a LEFT JOIN sys_user b ON a.user_id=b.user_id LEFT JOIN sys_menu c ON a.menu_code=c.menu_code WHERE 1=1"
	param := make([]any, 0)
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "a.ip_addr LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR "
			param = append(param, name)
			n++
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.UserId != "" {
		n++
		sqlStr += " AND a.user_id=$" + strconv.Itoa(n)
		param = append(param, req.UserId)
	}
	if req.MenuCode != "" {
		n++
		sqlStr += " AND a.menu_code=$" + strconv.Itoa(n)
		param = append(param, req.MenuCode)
	}
	if req.Kind != 0 {
		n++
		sqlStr += " AND a.kind=$" + strconv.Itoa(n)
		param = append(param, req.Kind)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND a.add_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND a.add_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	sqlStr += " ORDER BY a.add_time DESC LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	return db.GetAll(sqlStr, param...)
}
